package com.study.other;


import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference;

public class RouterService {

  private volatile AtomicReference<Pair> atomicReference = new AtomicReference<Pair>(
      new Pair().setCount(18));

  public static void main(String[] args) {

    RouterService test = new RouterService();
    test.test();
  }

  public void test() {
//    ScheduledThreadPoolExecutor scheduled = new ScheduledThreadPoolExecutor(2);
//    scheduled.scheduleAtFixedRate(new MyScheduleThread(), 0, 10L, TimeUnit.MILLISECONDS);
    int i = Runtime.getRuntime().availableProcessors();
    ExecutorService executorService = new ThreadPoolExecutor(i, i * 2, 600L, TimeUnit.SECONDS,
        new ArrayBlockingQueue<>(60));
    List<List<String>> list = splitList(newList(), i);
    try {
      for (List<String> one : list) {
        //阻塞和非阻塞的区别
        executorService.submit(new Run(one)).get();
//        executorService.submit(new Run(one));
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      executorService.shutdown();
    }
  }

  private void singleThreadDoSyncService(List<String> one) {
    for (String s : one) {
      atomicReference.updateAndGet((v) -> {
        Pair pair = atomicReference.get();
        System.out.println("test====>" + pair);
        v.setDown(Objects.isNull(pair.getDown()) ? 1 : pair.getDown() + 1);
        return v;
      });
    }
  }

  private List<String> newList() {
    List<String> list = new ArrayList<>();
    for (int i = 0; i < 18; i++) {
      list.add(i + "");
    }
    return list;
  }

  private class Run implements Callable<Objects> {

    final List<String> one;

    public Run(List<String> one) {
      this.one = one;
    }

    @Override
    public Objects call() throws Exception {
      for (String s : one) {
        final Pair pair1 = atomicReference.updateAndGet((v) -> {
          Pair pair = atomicReference.get();
          v.setDown(Objects.isNull(pair.getDown()) ? 1 : pair.getDown() + 1);
          return v;
        });
      }
      return null;
    }
  }

  private List<List<String>> splitList(List<String> list, int n) {
    List<List<String>> result = new ArrayList<>();
    int remainder = list.size() % n;
    int number = list.size() / n;
    int offset = 0;
    for (int i = 0; i < n; i++) {
      List<String> value;
      if (remainder > 0) {
        value = list.subList(i * number + offset, (i + 1) * number + offset + 1);
        remainder--;
        offset++;
      } else {
        value = list.subList(i * number + offset, (i + 1) * number + offset);
      }
      result.add(value);
    }
    return result;
  }


  private static class Pair {

    private volatile Integer count;
    private volatile Integer down;

    public Integer getCount() {
      return count;
    }

    public Pair setCount(Integer count) {
      this.count = count;
      return this;
    }

    public Integer getDown() {
      return down;
    }

    public Pair setDown(Integer down) {
      this.down = down;
      return this;
    }

    @Override
    public String toString() {
      return "Pair{" +
          "count=" + count +
          ", down=" + down +
          '}';
    }
  }


  private class MyScheduleThread implements Runnable {

    @Override
    public void run() {
      System.out.println(atomicReference.get());
    }
  }


}
